package org.unidata.mdm.meta.service.impl.data.instance;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.unidata.mdm.core.type.model.EntitiesGroupElement;
import org.unidata.mdm.core.type.model.LookupElement;
import org.unidata.mdm.core.type.model.RegisterElement;
import org.unidata.mdm.core.type.model.instance.AbstractNamedDisplayableImpl;
import org.unidata.mdm.meta.type.instance.DataModelInstance;
import org.unidata.mdm.meta.type.model.entities.EntitiesGroup;
import org.unidata.mdm.system.type.support.IdentityHashSet;

/**
 * @author Mikhail Mikhailov on Oct 20, 2020
 */
public class EntitiesGroupImpl extends AbstractNamedDisplayableImpl implements EntitiesGroupElement {
    /**
     * The source group.
     */
    private final EntitiesGroup group;
    /**
     * The path.
     */
    private final String path;
    /**
     * Registers.
     */
    private final Set<RegisterElement> registers = new IdentityHashSet<>();
    /**
     * Lookups.
     */
    private final Set<LookupElement> lookups = new IdentityHashSet<>();
    /**
     * Children.
     */
    private final List<EntitiesGroupElement> children;
    /**
     * Constructor.
     * @param path the current path
     * @param group the group
     * @param dmi instance
     */
    public EntitiesGroupImpl(String path, EntitiesGroup group, DataModelInstance dmi) {
        super(group.getName(), group.getDisplayName());
        this.group = group;
        this.path = StringUtils.isBlank(path) ? group.getName() : path + '.' + group.getName();
        this.children = group.getInnerGroups().stream()
            .map(v -> new EntitiesGroupImpl(this.path, v, dmi))
            .collect(Collectors.toCollection(ArrayList<EntitiesGroupElement>::new));
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getId() {
        return getPath();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getPath() {
        return path;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<RegisterElement> getRegisters() {
        return registers;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<LookupElement> getLookups() {
        return lookups;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<EntitiesGroupElement> getChildren() {
        return children;
    }
    /**
     * Gets the source. Needed for model assembling.
     * @return source
     */
    public EntitiesGroup getSource() {
        return group;
    }

    void addRegister(RegisterElement el) {
        registers.add(el);
    }

    void addLookup(LookupElement el) {
        lookups.add(el);
    }
}
